//项目开发者邮箱：zhangzhibo@vittor.cn。
//如若你有兴趣与我一同探讨相关项目，可以加我的QQ：979224302。
//让我们一起为开源做一份贡献，提供建议，并且能够共享这些建议。

#include <EEPROM.h>
//写入EEPROM第0位
int addw = 0;
//读取EEPROM第0位
int addr = 0;

//建立默认的密码数组
static int psw[6] = {EEPROM.read(0), EEPROM.read(1), EEPROM.read(2), EEPROM.read(3), EEPROM.read(4), EEPROM.read(5)};
//建立输入密码的数组
int btn_input[6] = {};
//密码位数计数器
int btn_counter = 0;

//继电器
const int relay = 14;
//蜂鸣器
const int buzzer = 13;
//按钮指示灯（绿色）
const int btn_LED = 15;
//按钮矩阵
const int one = 2;
const int two = 3;
const int three = 4;
const int four = 5;
const int five = 6;
const int six = 7;
const int seven = 8;
const int eight = 9;
const int nine = 10;
const int zero = 11;
const int key_reset = 12; //密码输入复位
const int pwd_change = 19; //修改密码使用
//初始化按钮矩阵全部为未按下状态
int btn_1 = LOW;
int btn_2 = LOW;
int btn_3 = LOW;
int btn_4 = LOW;
int btn_5 = LOW;
int btn_6 = LOW;
int btn_7 = LOW;
int btn_8 = LOW;
int btn_9 = LOW;
int btn_0 = LOW;
int  btn_key_reset = LOW ;
int btn_pwd_change = LOW;

void setup() {

  //按钮矩阵初始化
  pinMode(one, INPUT);
  pinMode(two, INPUT);
  pinMode(three, INPUT);
  pinMode(four, INPUT);
  pinMode(five, INPUT);
  pinMode(six, INPUT);
  pinMode(seven, INPUT);
  pinMode(eight, INPUT);
  pinMode(nine, INPUT);
  pinMode(zero, INPUT);
  pinMode(key_reset, INPUT);//密码输入复位按钮初始化
  pinMode(pwd_change, INPUT); //密码修改按钮初始化
  //继电器初始化
  pinMode(relay, OUTPUT);
  //按钮指示灯初始化
  pinMode(btn_LED, OUTPUT);
  //初始化与初始化完成后激活蜂鸣器
  pinMode(buzzer, OUTPUT);
  digitalWrite(buzzer, HIGH);
  delay(500);
  digitalWrite(buzzer, LOW);
}

//按钮按下事件
void btn_down(int LED, int buz, int t) {
  digitalWrite(btn_LED, LED);
  digitalWrite(buzzer, buz);
  delay(t);//延迟t秒，作用是防止一次读取一连串的同一按钮、
  digitalWrite(buzzer, LOW);
  digitalWrite(btn_LED, LOW);
}

void loop() {

  //计数器
  int i = 0, j = 0;

  //初始化按钮矩阵
  btn_1 = digitalRead(one);
  btn_2 = digitalRead(two);
  btn_3 = digitalRead(three);
  btn_4 = digitalRead(four);
  btn_5 = digitalRead(five);
  btn_6 = digitalRead(six);
  btn_7 = digitalRead(seven);
  btn_8 = digitalRead(eight);
  btn_9 = digitalRead(nine);
  btn_0 = digitalRead(zero);
  btn_key_reset = digitalRead(key_reset);
  btn_pwd_change = digitalRead(pwd_change);

  //按钮数组
  int btn_num[12] = {btn_0, btn_1, btn_2, btn_3, btn_4, btn_5, btn_6, btn_7, btn_8, btn_9, btn_key_reset, btn_key_reset};

  //监听0~9按钮
  for (int i = 0; i < 10; i++) {
    if (btn_num[i] == HIGH) {
      btn_input[btn_counter++] = i;
      btn_down (HIGH, LOW, 800);
    }
  }
  if (btn_key_reset == HIGH) {//如果密码输入复位按钮为按下状态
    for (int i = 0; i <= 5; i++) {
      btn_input[i] = ' ';
    }
    btn_down (HIGH, HIGH, 200);
    btn_counter = 6;
  }
  else if (btn_pwd_change == HIGH) { //如果修改密码按钮为按下状态
    btn_down (HIGH, HIGH, 100);
    while (true) {

      //给new_pwd赋予初值为10，用于判断是否按下0~9按钮
      int new_pwd = 10;

      //初始化按钮矩阵
      btn_1 = digitalRead(one);
      btn_2 = digitalRead(two);
      btn_3 = digitalRead(three);
      btn_4 = digitalRead(four);
      btn_5 = digitalRead(five);
      btn_6 = digitalRead(six);
      btn_7 = digitalRead(seven);
      btn_8 = digitalRead(eight);
      btn_9 = digitalRead(nine);
      btn_0 = digitalRead(zero);
      btn_key_reset = digitalRead(key_reset);
      btn_pwd_change = digitalRead(pwd_change);
      //按钮数组
      int btn_num[12] = {btn_0, btn_1, btn_2, btn_3, btn_4, btn_5, btn_6, btn_7, btn_8, btn_9, btn_key_reset, btn_key_reset};
      //监听0~9按钮
      for (int i = 0; i < 10; i++) {
        if (btn_num[i] == HIGH) {
          new_pwd = i;
          btn_down (HIGH, HIGH, 800);
        }
      }

      //如果new_pwd小于10，则执行
      if (new_pwd < 10) {
        EEPROM.write(addw, new_pwd);//写入EEPROM中的第addw位
        addw++;//下一次写入下一位
      }
      if (addw > 5) {//密码设置完成
        addw = 0;//清除位
        while (true) {
          delay(100);
          digitalWrite(buzzer, HIGH);//蜂鸣器长鸣
          delay(100);
          digitalWrite(buzzer, LOW);
        }
      }
    }
  }

  //判断是否输入了6位密码
  if (btn_counter == 6) {

    //逐位判断密码是否相同
    for (int i = 0 ; i < btn_counter; i++) {
      if (psw[i] == btn_input[i]) {
        j++;//如果位密码相同则自加1
      }
    }

    //如果全部位密码相同，那么j应该等于btn_counter.
    if (j == btn_counter) {
      digitalWrite(relay, HIGH);
      digitalWrite(btn_LED, HIGH);
      digitalWrite(buzzer, HIGH);
      delay(250);
      digitalWrite(buzzer, LOW);
      delay(1500);
      digitalWrite(buzzer, HIGH);
      delay(250);
      digitalWrite(buzzer, LOW);
      digitalWrite(btn_LED, LOW);
      btn_counter = 0;
    } else {
      btn_counter = 0;
    }
    digitalWrite(relay, LOW);
  }
}
